home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 November: Tool Chest / Dev.CD Nov 98 TC.toast / Sample Code / Devices / ADB Key Spy 1.0.1b3 / ADBKS Service Routine.c < prev    next >
Encoding:
Text File  |  1997-03-07  |  3.9 KB  |  150 lines  |  [TEXT/R*ch]

  1.     //
  2.     //    ADB Key Spy Service Routine • Pete Gontier • gurgle@apple.com
  3.     //    Macintosh Developer Technical Support
  4.     //    © 1995,1996 Apple Computer, Inc.
  5.     //
  6.     //    Changes:
  7.     //
  8.     //        when        who        what
  9.     //        --------------------------------------------------------------
  10.     //        08/23/95    PG        history begins
  11.     //        08/24/95    PG        service routines split off into separate
  12.     //                            code resource for use with PowerPC
  13.     //        09/11/95    PG        first cut at virtual key map support
  14.     //        09/11/95    PG        better third-party compatibility
  15.     //        01/11/96    PG        moved to extension-based project
  16.     //
  17.  
  18. #ifndef __A4STUFF__
  19. #    include <A4Stuff.h>
  20. #endif
  21.  
  22. #include "ADBKS Common.h"
  23.  
  24. static pascal void KeyboardServiceRoutineC (ConstStr255Param, tKeyboardInfo *);
  25. asm void __Startup__ (void);
  26.  
  27.     //
  28.     //    myDebugStr
  29.     //    DebugStrIf
  30.     //
  31.     //    These are two simple macros to aid in debugging the service routine.
  32.     //    You pretty much can't expect to use MacsBug while the service routine
  33.     //    (or any code it calls) is running. Why? Because MacsBug uses ADB to
  34.     //    talk to keyboards, and if ADB (this code) is buggy... well, you can't
  35.     //    type. If you need to debug the service routine, I suggest embedding
  36.     //    MacsBug commands in DebugStr strings followed by '; g', and
  37.     //    don't change any keys while the command is running.
  38.     //
  39.  
  40. #define myDebugStr(x) \
  41.     do { long oldA4 = SetCurrentA4 ( ); DebugStr (x ";g"); SetA4 (oldA4); } while (0)
  42. #define myDebugStrIf(x) \
  43.     do { if (x) myDebugStr("\p" #x); } while (0)
  44.  
  45.     //
  46.     //    __Startup__
  47.     //
  48.     //    The basic idea here is to extract the information from the
  49.     //    ADB interrupt message, then call the old service routine so
  50.     //    that GetKeys still works for other folks. The interface for
  51.     //    this routine is documented in Inside Mac V-371.
  52.     //
  53.  
  54. asm void __Startup__ (void)
  55. {
  56.     //
  57.     //    is it a 'Talk' message?
  58.     //
  59.  
  60.     BTST        #2,D0
  61.     BEQ.S        bail                        // no
  62.     BTST        #3,D0
  63.     BEQ.S        bail                        // no
  64.  
  65.     //
  66.     //    is it for register 0?
  67.     //
  68.  
  69.     BTST        #0,D0
  70.     BNE.S        bail                        // no
  71.     BTST        #1,D0
  72.     BNE.S        bail                        // no
  73.  
  74.     //
  75.     //    call C function to track key change
  76.     //
  77.  
  78.     MOVEM.L        A0-A1/D0-D1,-(A7)            // save registers
  79.     MOVE.L        A0,-(A7)                    // pass ADB data buffer
  80.     MOVE.L        A2,-(A7)                    // pass private data address
  81.     JSR            KeyboardServiceRoutineC        // Geronimo!
  82.     MOVEM.L        (A7)+,A0-A1/D0-D1            // restore registers
  83.  
  84. bail:
  85.  
  86.     MOVE.L    (A2),-(A7)                        // push the previous service routine address
  87.     MOVE.L    4(A2),A2                        // set up the previous private data address
  88.     RTS                                        // jump to old service routine
  89. }
  90.  
  91.     //
  92.     //    KeyboardServiceRoutineC
  93.     //
  94.     //    This routine is called from the (68K assembly) service routine.
  95.     //    Given a pointer to a copy of the keyboard's register 0 and
  96.     //    the keyboard map for the keyboard, it updates the map.
  97.     //    Note that A5 (or A4, as the case may be) is not valid here,
  98.     //    so you will have to perform arcane rites to access global variables.
  99.     //
  100.  
  101. #pragma parameter SetD1 (__D1)
  102. void SetD1 (long) = { 0x4E71 };
  103.  
  104. static pascal void KeyboardServiceRoutineC (ConstStr255Param adbDataBuffer, tKeyboardInfo *kbInfo)
  105. {
  106.     //
  107.     //    Sanity check: have we been passed the expected number of bytes?
  108.     //
  109.  
  110.     if (adbDataBuffer [0] == 2)
  111.     {
  112.         //
  113.         //    Find the the virtual key map entry affected by the
  114.         //    given raw key code. If there is no translator resource,
  115.         //    don't translate.
  116.         //
  117.     
  118.         unsigned char        *keyMapEntry        = kbInfo->virtualKeyMap;
  119.         tKeyMapResourceH    keyMapResH            = kbInfo->keyMapResH;
  120.         unsigned char        adbDataBufferIndex    = 1;
  121.  
  122.         do
  123.         {
  124.             unsigned char adbByte = adbDataBuffer [adbDataBufferIndex];
  125.  
  126.             if (adbByte != 0xFF)
  127.             {
  128.                 unsigned char rawKeyCodeIndex = 0x7F & adbByte;
  129.             
  130.                 if (!keyMapResH)
  131.                     keyMapEntry += rawKeyCodeIndex;
  132.                 else
  133.                     keyMapEntry += (**keyMapResH).map [rawKeyCodeIndex];
  134.             
  135.                 //
  136.                 //    If a key is going down, increment its counter.
  137.                 //    If instead it's going up, make sure its counter
  138.                 //    can be decremented before decrementing it.
  139.                 //
  140.             
  141.                 if (!(0x80 & adbByte))
  142.                     *keyMapEntry += 1;
  143.                 else if (*keyMapEntry)
  144.                     *keyMapEntry -= 1;
  145.             }
  146.         }
  147.         while (++adbDataBufferIndex <= 2);
  148.     }
  149. }
  150.